#include "Socket.h"

#include <sys/poll.h>

using namespace std;
using namespace efs;

Socket2::Socket2(const int listener)
	: m_listener(listener)
	, m_socket(0)
	, m_receive_timeout (2)
	, m_transmitt_timeout (2)
{
	pantheios::log_DEBUG("[Socket]: Connection opened");

	m_socket = accept(m_listener, NULL, NULL);
	if (m_socket < 0)
	{
		pantheios::log_ERROR("[Socket]: Accept error");
		m_socket = 0;
		return;
	}

	fcntl(m_socket, F_SETFL, O_NONBLOCK);
}

Socket2::~Socket2()
{
	if (m_socket)
	{
		close(m_socket);
	}
}

size_t Socket2::read(char *data, size_t size)
{
	if (waitForEvent() == false)
	{
		return -1;
	}
	int bytes_read = recv(m_socket, data, size, 0);

	if (bytes_read < 0)
	{
		pantheios::log_ERROR("[Socket]: Reading from socket error");
	}
	return bytes_read;
}

int Socket2::write(char *data, size_t size)
{
	/* checking if connection is still alive*/
	struct pollfd ufds[1];
	ufds[0].fd = m_socket;
	ufds[0].events = POLLOUT;
	int rv = poll(ufds, 1, 0);
	if (rv == -1 || (ufds[0].revents & POLLERR) || (ufds[0].revents & POLLHUP))
	{
		pantheios::log_ERROR("[Socket]: Data transmission error (lost connection)");
		return 0;
	}

	send(m_socket, data, size, 0);

	/* structure for transmit control */
	fd_set writeset;
	FD_ZERO(&writeset);
	FD_SET(m_socket, &writeset);

	/* setting timeout */
	timeval timeout;
	timeout.tv_sec = m_transmitt_timeout;
	timeout.tv_usec = 0;

	/* waiting for transmission end */
	if (select(m_socket + 1, NULL, &writeset, NULL, &timeout ) <= 0)
	{
			pantheios::log_ERROR("[Socket]: Data transmission error (timeout)");
			return 0;
	}

	return 1;
}

bool Socket2::waitForEvent(void)
{
	/* structure for read control */
	fd_set readset;
	FD_ZERO(&readset);
	FD_SET(m_socket, &readset);

	/* set the timeout */
	timeval timeout;
	timeout.tv_sec = m_receive_timeout;
	timeout.tv_usec = 0;

	/* waiting for event in socket */
	if (select(m_socket + 1, &readset, NULL, NULL, &timeout) <= 0)
	{
		pantheios::log_ERROR("[Socket]: Data read error (timeout)");
		return false;
	}
	else
	{
		return true;
	}
}
